package com.card.vault.controller;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;

import myPackage.Text_Convertion;

import org.apache.log4j.Logger;
import org.json.simple.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.card.vault.domain.another.Card;
import com.card.vault.domain.another.CardType;
import com.card.vault.domain.user.User;
import com.card.vault.service.CardService;
import com.card.vault.service.UserService;

@Controller
public class UserController {

	private static final Logger logger = Logger.getLogger(UserController.class);
	
	@Autowired
    private UserService userService;
	
	@Autowired
    private CardService cardService;
	
	private static Random random = new Random();
    static int generateRandom(int n) {
        return Math.abs(random.nextInt()) % n;
    }
	
    
	@RequestMapping(value = "/register", method = RequestMethod.GET)
	public String link_Register(Map<String, Object> map) {
		//User
		User user = new User();
		map.put("user", user);
		//User Names in DB
		/*List<String> userNameList = new ArrayList<String>();
		List<User> userList = userService.userList();
		Iterator<User> userListIterator = userList.iterator();
		while(userListIterator.hasNext())
			userNameList.add(userListIterator.next().getName());
		map.put("userNameList", userNameList);*/
		//Random ID for new user
		int rand = generateRandom(10000);
		List<User> users = userService.userList();
		Iterator<User> userIterator = users.iterator();
		if (userIterator.hasNext()) {
			while( userIterator.next().getId() == rand || rand < 1000 )
				rand = generateRandom(10000);
		}
		map.put("userID", rand);
		return "register";
	}
	
	@RequestMapping(value = "/user/registration", method = RequestMethod.POST)
    public String userRegistration( @ModelAttribute("user") User user, 
    								@RequestParam("CardNumbers") List<String> CardNumbers,
					    			@RequestParam("CardTypes") List<String> CardTypes ){
		logger.info("The user '"+user.getName()+"' is logged.");
		List<Card> Card = new ArrayList<Card>();
		Iterator<String> cardTypesIterator = CardTypes.iterator();
		Iterator<String> CardTypesIteratorForLoggerIterator = Text_Convertion.remakeListForLogger(CardTypes).iterator();
		Iterator<String> cardNumbersIterator = CardNumbers.iterator();
		while( cardTypesIterator.hasNext() ) {
			Card card = new Card();
			String cardType = cardTypesIterator.next();
			String cardNumber = cardNumbersIterator.next();
			card.setCardType(CardType.valueOf(cardType));
			card.setCardNumber(cardNumber);
			card.setUser(user);
			Card.add(card);
			logger.info(user.getName()+" card"+": "+CardTypesIteratorForLoggerIterator.next()+" - "+cardNumber+";");
		}
		user.setCard(Card);
		userService.saveUser(user);
		return "redirect:/home";
	}

	//JSON
	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/user/hasInDB", method = {RequestMethod.POST})
    public @ResponseBody JSONObject hasInDB(
    		@RequestParam String user_name,
    		@RequestParam String cell_number,
    		@RequestParam String user_password,
    		@RequestParam("card_numbers") List<String> card_numbers,
    		@RequestParam("card_types") List<String> card_types) {
		
		JSONObject obj = new JSONObject();
		JSONObject obj_card = new JSONObject();
		boolean has_in_db = false;
		
		obj.put("name", user_name);
		obj.put("password", user_password);
		obj.put("cell_number", cell_number);
		
		Iterator<String> cardTypesIterator = card_types.iterator();
		Iterator<String> cardNumbersIterator = card_numbers.iterator();
		while(cardTypesIterator.hasNext()) {
			obj_card.put(cardTypesIterator.next(), cardNumbersIterator.next());
		}
		obj.put("cards", obj_card);
		
		List<User> userList = userService.userList();
		Iterator<User> usersIterator = userList.iterator();
		while(usersIterator.hasNext()) {
			User user = usersIterator.next();
			if ( user.getName().toLowerCase().equals(user_name.toLowerCase()) ) {
				has_in_db = true;
				break;
			}
		}
		obj.put("has_in_db", has_in_db);
		logger.info("JSON test: " + obj);
		return obj;
	}
	//JSON
	
	@RequestMapping(value = "/myaccount", method = RequestMethod.GET)
	public String link_MyAccount(Map<String, Object> map) {
		User user = userService.retriveUser(SecurityContextHolder.getContext().getAuthentication().getName());
		map.put("cardlist", user.getCard());
		return "myaccount";
	}
	
	@RequestMapping(value = "/user/delete_card/{card_id}", method = RequestMethod.GET)
    public String deleteCard(@PathVariable("card_id") int card_id) {
	    Card card = cardService.retriveCard(card_id);
	    User user = card.getUser();
	    user.getCard().remove(card);
	    userService.saveUser(user);
	    cardService.removeCard(card_id);
	    logger.info("User " + user.getName() + " remove card " + card.getCardType() + " - " + card.getCardNumber());
	    return "redirect:/myaccount";
    }
	
}